import axios from 'axios'
import NProgress from 'nprogress'

/**
 * 存储了环境变量的对象
 *
 * @type {ImportMetaEnv}
 */
const env = import.meta.env

/**
 * 创建 axios 实例对象
 *
 * @type {axios.AxiosInstance}
 */
const req = axios.create({
    // 配置 axios 实例对象发送请求时的基础地址, 使用环境变量 (webpack 中使用环境变量形式: process.env.BASE_API)
    // 为了适应多个后台或者开发的时候的 api 地址和发布的时候的 api 地址不一样这种情况
    // VITE_SERVER_HOST: 服务端程序所在的主机 IP
    // VITE_SERVER_PORT: 服务端程序在所在主机中运行监听的端口号
    // VITE_SERVER_BASEURL: 服务端程序访问的上下文路径
    baseURL: `http://${env.VITE_SERVER_HOST}:${env.VITE_SERVER_PORT}${env.VITE_SERVER_BASEURL}`,
    // 请求超时时间, 单位是 ms, 这里设置了 3s 的超时时间
    timeout: env.VITE_REQUEST_TIMEOUT
})

/**
 * 请求拦截器
 */
req.interceptors.request.use(
    (config) => {
        // 开始加载条
        NProgress.start()
        return config
    },
    (error) => {
        // 结束加载条
        NProgress.done()
        //提示错误信息
        // message.error(msg)
        ElMessage({
            message: '请求发送失败',
            type: 'error',
        })
        return Promise.reject(error)
    }
)

/**
 * 为 axios 实例对象配置响应拦截器, 对服务端响应进行统一处理,
 * 如: 错误响应统一处理, 简化响应数据等
 */
req.interceptors.response.use(
    // 成功响应的统一处理
    response => {
        // 结束加载条
        NProgress.done()
        // 响应数据中的状态编码
        const code = response.data.code
        // 响应数据中的响应信息
        const msg = response.data.message
        // 进行非网络错误，业务逻辑错误的响应信息处理
        if (code !== 200) {
            //提示错误信息
            // message.error(msg)
            ElMessage({
                message: msg,
                type: 'error',
            })
        } else {
            //提示成功信息
            // message.success(msg)
            ElMessage({
                message: msg,
                type: 'success',
            })
        }
        // 简化响应数据
        return Promise.resolve(response.data.data)
    },
    // 失败响应的统一处理
    error => {
        // 结束加载条
        NProgress.done()
        // 定义一个变量: 存储错误提示信息
        let msg = ''
        // 如果发生错误
        if (error && error.response) {
            // 根据响应码进行相应的具体处理
            switch (error.response.status) {
                case 400:
                    msg = '错误请求'
                    break;
                case 401:
                    msg = '未授权，请重新登录'
                    break;
                case 403:
                    msg = '拒绝访问'
                    break;
                case 404:
                    msg = '请求错误,未找到该资源'
                    break;
                case 405:
                    msg = '请求方法未允许'
                    break;
                case 408:
                    msg = '请求超时'
                    break;
                case 500:
                    msg = '服务器端出错'
                    break;
                case 501:
                    msg = '网络未实现'
                    break;
                case 502:
                    msg = '网络错误'
                    break;
                case 503:
                    msg = '服务不可用'
                    break;
                case 504:
                    msg = '网络超时'
                    break;
                case 505:
                    msg = 'http 版本不支持该请求'
                    break;
                default:
                    msg = `连接错误${error.response.status}`
            }
        } else {
            // 超时处理
            if (JSON.stringify(error).includes('timeout')) {
                msg = '服务器响应超时，请刷新当前页'
            }
            msg = '连接服务器失败'
        }
        // 提示错误信息
        // message.error(msg)
        ElMessage({
            message: msg,
            type: 'error',
        })
        return Promise.reject(error)
    }
)

/**
 * 导出 axios 实例对象
 */
export default req